package com.huatai.bpmn.service.impl;

import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.huatai.bpmn.constant.PMPConstant;
import com.huatai.bpmn.entity.*;
import com.huatai.bpmn.entity.vo.HistoryVO;
import com.huatai.bpmn.service.BasicDataService;
import com.huatai.bpmn.service.BasicLoadService;
import com.huatai.common.entity.UserInfo;
import com.huatai.common.error.exception.ServiceException;
import com.huatai.common.util.AuthUtil;
import com.huatai.common.util.BeanUtil;
import com.huatai.common.util.ObjectUtil;
import com.huatai.user.dubbo.UserDubboApi;
import com.huatai.user.vo.UserVo;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.huatai.bpmn.mapper.InvestCapitalMapper;
import com.huatai.bpmn.service.InvestCapitalService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 实施详情表格
 *
 * @author yxy
 * @email yuanxy999@126.com
 * @date 2024-07-19 10:41:47
 */
@Service("investCapitalService")
public class InvestCapitalServiceImpl extends ServiceImpl<InvestCapitalMapper, InvestCapitalEntity> implements InvestCapitalService {
	@DubboReference(timeout = 30000, check = false, retries = 0)
	private UserDubboApi userDubboApi;
	@Autowired
	private InvestCapitalMapper investCapitalMapper;

	@Autowired
	private BasicDataService basicDataService;
	@Autowired
	private BasicLoadService basicLoadService;

	/**
	 * 根据用户查询用户实施列表
	 *
	 * @param flowId
	 * @return
	 */
	@Override
	public Map<String, List<InvestCapitalEntity>> getList(String flowId) {
		UserInfo user = AuthUtil.getUser();
		Long userId = user.getUserId();
		/**
		 * 项目经理可以查看所有相关的实施人员人工天数据
		 * 实施成员可以查看自己的人工天数据
		 * 刘总-财务部主任-市场部帆哥、主任（胡凯）、副主任（刘萍萍）-项目协同中心-池金余、赵余桐、方清锐可以看见所有
		 */
		String xmjl = basicLoadService.getPmpValue("xmjl", flowId);
		boolean flag = userDubboApi.getRoleByUserId(userId);
		HashMap<String, List<InvestCapitalEntity>> map = new HashMap<>();
		//所有项目数据(领导和项目经理)
		if (flag || user.getRealName().equals(xmjl)) {
			//查询项目所有的用户
			List<JSONObject> userList = investCapitalMapper.getUserIdByFlowId(flowId);
			userList.forEach(x -> {
				String userids = x.getOrDefault("user_id", "").toString();
				String userName = x.getOrDefault("user_name", "").toString();
				List<InvestCapitalEntity> investList = investCapitalMapper.getListByUserIdAndFlowId(userids, flowId);
				map.put(userName, investList);
			});
		} else {
			List<InvestCapitalEntity> investList = investCapitalMapper.getListByUserIdAndFlowId(userId.toString(), flowId);
			map.put(user.getRealName(), investList);
		}
		return map;
	}

	@Override
	public boolean delete(Long id) {
		InvestCapitalEntity investCapitalEntity = this.getById(id);
		if (ObjectUtil.isEmpty(investCapitalEntity)) {
			throw new ServiceException("对象为空");
		}
		if (!AuthUtil.getUser().getRealName().equals(investCapitalEntity.getProjectManager())) {
			throw new ServiceException("只有项目经理可以删除数据");
		}
		return this.removeById(id);
	}

	/**
	 * 发起数据新增和修改
	 *
	 * @param investCapitalEntity
	 * @return
	 * @jsonObject 项目数据
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean addOrUpd(InvestCapitalEntity investCapitalEntity) {
		//获取项目经理
		String flowId = investCapitalEntity.getFlowId();
		String xmjl = basicLoadService.getPmpValue("xmjl", flowId);
		//获取项目经理用户信息
		UserVo userInfo = userDubboApi.findUserInfoByRealName(xmjl);
		if (ObjectUtil.isEmpty(userInfo)) {
			throw new ServiceException("该项目没有项目经理，请添加项目经理后再尝试");
		}
		investCapitalEntity.setProjectManager(xmjl);//存入项目经理名称
		UserInfo user = AuthUtil.getUser();
		investCapitalEntity.setUserId(user.getUserId());
		investCapitalEntity.setUserName(user.getRealName());

		//项目经理可以直接新增修改数据
		if (user.getRealName().equals(xmjl)) {
			investCapitalEntity.setCheckStatus(PMPConstant.STATUS_0);
			return this.saveOrUpdate(investCapitalEntity);
		}
		//区分提前投入、实施人工天、运维详情
//		String myKey = PMPConstant.TABLE_SS_INFO;
		String myKey = investCapitalEntity.getMyKey();
		BasicDataEntity basicDataEntity = new BasicDataEntity();
		//新增数据待审核，修改数据需要查看状态是否为待审核，如果为待审核则不能操作

		if (investCapitalEntity.getId() == null) {
			basicDataEntity.setAddUpd(PMPConstant.DATA_ADD);
			investCapitalEntity.setCheckStatus(PMPConstant.STATUS_1);
			this.saveOrUpdate(investCapitalEntity);//保存数据
		} else {
			InvestCapitalEntity capitalEntity = this.getById(investCapitalEntity.getId());
			if (PMPConstant.STATUS_1.equals(capitalEntity.getCheckStatus())) {
				throw new RuntimeException("当前数据正在审核中");
			}
		}


		//1.获得engine对象
		ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
		RuntimeService runtimeService = engine.getRuntimeService();
		TaskService taskService = engine.getTaskService();
		//5.根据流程定义（类）生成流程实例（对象），借助RuntimeService
		//修改审批，其他暂时不用
		HashMap<String, Object> map = new HashMap<>();
		map.put("assignee0", user.getUserId());
		map.put("assignee1", userInfo.getId());
		map.put("assignee2", PMPConstant.USER_ID_CJY);
		map.put("assignee3", PMPConstant.USER_ID_ZYT);
		map.put("assignee4", PMPConstant.USER_ID_FQR);
		map.put("flag", "true");//第一次提交默认为true
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(myKey, investCapitalEntity.getId().toString(), map);
		Task task = taskService.createTaskQuery().processDefinitionKey(myKey).processInstanceId(processInstance.getId())
			.taskAssignee(user.getUserId().toString()).singleResult();
		if (task != null) {
			taskService.complete(task.getId());
			System.out.println("任务执行完毕");
		}
		//保存数据
		basicDataEntity.setProcessId(processInstance.getId());
		basicDataEntity.setMyKey(myKey);
		basicDataEntity.setCreator(user.getUserId());
		basicDataEntity.setFlowId(investCapitalEntity.getId().toString());

		basicDataEntity.setParam(JSON.toJSONString(investCapitalEntity));
		basicDataEntity.setCreateTime(LocalDateTime.now());
		basicDataEntity.setStatus(PMPConstant.STATUS_1);
		basicDataService.save(basicDataEntity);
		return false;
	}

	/**
	 * 根据id查询数据
	 *
	 * @param id
	 * @return
	 */
	@Override
	public InvestCapitalEntity detailById(Long id) {
		BasicDataEntity basicDataEntity = basicDataService.getByFlowIdAndStatus(id);
		if (ObjectUtil.isEmpty(basicDataEntity)) {
			throw new ServiceException("查询数据为空");
		}
		String param = basicDataEntity.getParam();
		InvestCapitalEntity investCapitalEntity = JSON.parseObject(param, InvestCapitalEntity.class);
		return investCapitalEntity;
	}

	@Override
	public List<HistoryVO> taskHistoryInfo(String processId) {
		return this.getBaseMapper().taskHistoryInfo(processId);
	}

}
